/********************************************************************
	created:	2011/03/05
	created:	5:3:2011   22:36
	filename: 	C:\Users\lian\Documents\Visual Studio 2010\Projects\RSAEncryptor\src\LargeIntegerSpecialization.inl
	file path:	C:\Users\lian\Documents\Visual Studio 2010\Projects\RSAEncryptor\src
	file base:	LargeIntegerSpecialization
	file ext:	inl
	author:		Jincheng Li
	
	purpose:	
*********************************************************************/

#define DECL_SPECIAL_CONSTRUCTOR(T) \
	public: \
	LargeIntegerMeta(const T* ppstart){ \
		m_data[0] = *ppstart;\
	}\
	LargeIntegerMeta(const T pval){\
		m_data[0] = pval;\
	}


//************************************
// Partial specialization.
//************************************
template<typename ELEMT_TYP>
class LargeIntegerMeta<ELEMT_TYP, 1> {
public:
	DECL_SPECIAL_CONSTRUCTOR(ELEMT_TYP)

	LargeIntegerMeta<ELEMT_TYP, 2> operator * (const LargeIntegerMeta& rhs) const
	{
		const int HALF_ELEMT_BITS = sizeof(ELEMT_TYP)*4;
		const ELEMT_TYP upper_half_mask = (~(ELEMT_TYP(0x0)))<<HALF_ELEMT_BITS;
		const ELEMT_TYP lower_half_mask = ~upper_half_mask;

		const ELEMT_TYP a1 = (m_data[0]&upper_half_mask)>>HALF_ELEMT_BITS,		a2 = m_data[0]&lower_half_mask;
		const ELEMT_TYP b1 = (rhs.m_data[0]&upper_half_mask)>>HALF_ELEMT_BITS,	b2 = rhs.m_data[0]&lower_half_mask;

		const ELEMT_TYP r[] = { a2 * b2, a1 * b1};
		LargeIntegerMeta r_l_1(a1 * b2), r_l_2(a2 * b1);

		LargeIntegerMeta<ELEMT_TYP, 2> retVal(r);
		LargeIntegerMeta<ELEMT_TYP, 2> t_1(r_l_1),t_2(r_l_2);

		t_1 = t_1.left_shift_bits<HALF_ELEMT_BITS>();
		t_2 = t_2.left_shift_bits<HALF_ELEMT_BITS>();

		retVal = retVal + t_1 + t_2;

		return retVal;
	}


	ELEMT_TYP m_data[1];
};

template<>
class LargeIntegerMeta<UCHAR8,1> {
public:
	DECL_SPECIAL_CONSTRUCTOR(UCHAR8)

	LargeIntegerMeta<UCHAR8,2> operator * (const LargeIntegerMeta& rhs) const
	{
		UINT32 a = m_data[0], b = rhs.m_data[0];
		UINT32 r = a * b;
		LargeIntegerMeta<UCHAR8,2> ret((UCHAR8*)&r);
		return ret;
	}

	UCHAR8 m_data[1];
};

template<>
class LargeIntegerMeta<UINT32,1> {
public:
	DECL_SPECIAL_CONSTRUCTOR(UINT32)

		LargeIntegerMeta<UINT32,2> operator * (const LargeIntegerMeta& rhs) const
	{
		UINT64 a = m_data[0], b = rhs.m_data[0];
		UINT64 r = a * b;
		LargeIntegerMeta<UINT32,2> ret((UINT32*)&r);
		return ret;
	}

	UINT32 m_data[1];
};